import * as THREE from 'three'

/**
 * 异步模型处理器 - 防止模型处理阻塞主线程
 */
export class AsyncModelProcessor {
  constructor() {
    this.processingQueue = []
    this.isProcessing = false
  }

  /**
   * 异步处理模型（分帧执行）
   * @param {THREE.Object3D} model - 要处理的模型
   * @param {Function} onProgress - 进度回调
   * @returns {Promise<void>}
   */
  async processModel(model, onProgress = () => {}) {
    return new Promise((resolve) => {
      this.processingQueue.push({
        model,
        onProgress,
        resolve
      })
      
      if (!this.isProcessing) {
        this.startProcessing()
      }
    })
  }

  /**
   * 开始处理队列
   */
  async startProcessing() {
    if (this.isProcessing || this.processingQueue.length === 0) return
    
    this.isProcessing = true
    
    while (this.processingQueue.length > 0) {
      const task = this.processingQueue.shift()
      await this.processModelTask(task)
    }
    
    this.isProcessing = false
  }

  /**
   * 处理单个模型任务
   */
  async processModelTask({ model, onProgress, resolve }) {
    const meshes = []
    
    // 收集所有网格
    model.traverse((child) => {
      if (child.isMesh) {
        meshes.push(child)
      }
    })

    const total = meshes.length
    let processed = 0

    // 分批处理网格，每帧处理有限数量
    const batchSize = 5 // 每帧处理5个网格
    
    for (let i = 0; i < meshes.length; i += batchSize) {
      const batch = meshes.slice(i, i + batchSize)
      
      // 处理当前批次
      batch.forEach(mesh => {
        this.processMesh(mesh)
        processed++
        onProgress(Math.round((processed / total) * 100))
      })
      
      // 让出控制权给浏览器
      await this.nextFrame()
    }

    resolve()
  }

  /**
   * 处理单个网格
   */
  processMesh(mesh) {
    // 启用阴影
    mesh.castShadow = true
    mesh.receiveShadow = true
    
    // 处理材质
    if (mesh.material) {
      const materialsArray = Array.isArray(mesh.material) ? mesh.material : [mesh.material]
      
      materialsArray.forEach((material, index) => {
        this.processMaterial(material, mesh, index)
      })
    }

    // 优化几何体
    if (mesh.geometry) {
      this.optimizeGeometry(mesh.geometry)
    }
  }

  /**
   * 处理材质
   */
  processMaterial(material, mesh, index) {
    console.log(`处理材质 ${index}:`, material.type)
    
    // 修复黑色材质问题
    if (material.isMeshLambertMaterial || material.isMeshPhongMaterial) {
      const pbrMaterial = new THREE.MeshStandardMaterial({
        color: material.color || 0xffffff,
        map: material.map,
        normalMap: material.normalMap,
        roughness: 0.8,
        metalness: 0.1,
        transparent: material.transparent,
        opacity: material.opacity
      })
      
      // 如果有漫反射贴图但颜色是黑色，设置为白色
      if (material.map && material.color && material.color.getHex() === 0x000000) {
        pbrMaterial.color.setHex(0xffffff)
        console.log('修复黑色材质为白色')
      }
      
      // 替换材质
      if (Array.isArray(mesh.material)) {
        mesh.material[index] = pbrMaterial
      } else {
        mesh.material = pbrMaterial
      }
      
      material = pbrMaterial
    }
    
    // 确保材质有基本颜色
    if (material.color && material.color.getHex() === 0x000000) {
      material.color.setHex(0xcccccc)
      console.log('修复全黑材质为浅灰色')
    }
    
    // 调整PBR材质参数
    if (material.isMeshStandardMaterial) {
      if (material.metalness === undefined || material.metalness > 0.9) {
        material.metalness = 0.2
      }
      
      if (material.roughness === undefined || material.roughness < 0.1) {
        material.roughness = 0.6
      }
      
      // 设置环境贴图强度
      material.envMapIntensity = 1.0
    }
    
    // 修复透明度问题
    if (material.opacity !== undefined && material.opacity < 0.1) {
      material.opacity = 1.0
      material.transparent = false
      console.log('修复低透明度材质')
    }
  }

  /**
   * 优化几何体
   */
  optimizeGeometry(geometry) {
    // 合并重复顶点
    if (geometry.attributes && !geometry.index) {
      geometry = THREE.BufferGeometryUtils.mergeVertices(geometry)
    }
    
    // 计算法线（如果没有）
    if (!geometry.attributes.normal) {
      geometry.computeVertexNormals()
    }
    
    // 计算包围盒和包围球
    geometry.computeBoundingBox()
    geometry.computeBoundingSphere()
  }

  /**
   * 等待下一帧
   */
  nextFrame() {
    return new Promise(resolve => {
      requestAnimationFrame(resolve)
    })
  }

  /**
   * 清理队列
   */
  clear() {
    this.processingQueue = []
    this.isProcessing = false
  }
}

// 创建全局实例
export const asyncModelProcessor = new AsyncModelProcessor()


